package xifileserver;

import java.util.ArrayList;

/**
 * Create a protocol message corresponding to the XiFile Protocol
 *
 * @see XiFile Protocol
 * @version 0.1
 * @author saluzzo
 */
public class ProtocolMessage {

    /**
     * Message type
     * @see XiFile Protocol
     */
    private String Type;

    /**
     * Message Parameters
     * @see XiFile Protocol
     */
    private ArrayList<String> ParametersList;

    /**
     * ProtocolMessage Constructor 
     * @param Type Message type
     * @param ParametersList Parameters list of message
     */
    public ProtocolMessage(String Type, ArrayList<String> ParametersList) {
        this.Type = Type;
        this.ParametersList = ParametersList;
    }

    /**
     * ProtocolMessage Constructor
     * @param Type Message type
     * @param ParametersList Parameters list of message in string table format
     */
    public ProtocolMessage(String Type, String[] ParametersList) {
        this.Type = Type;
        if(ParametersList != null) {
            this.ParametersList = new ArrayList<String>();
            for(int iParametersAdded = 0; iParametersAdded < ParametersList.length; iParametersAdded++) {
                this.ParametersList.add(ParametersList[iParametersAdded]);
            }
        } else {
            this.ParametersList = null;
        }
        
    }

    /**
     * ProtocolMessage Constructor
     * @param Type Message type
     * @param ParametersList Parameter of message
     */
    public ProtocolMessage(String Type, String Parameter) {
        this.Type = Type;
        if(ParametersList != null) {
            this.ParametersList = new ArrayList<String>();
            this.ParametersList.add(Parameter);
        } else {
            this.ParametersList = null;
        }
    }

    /**
     * ProtocolMessage Constructor
     * @param Message Message in ProtocoleMessage Object format
     */
    public ProtocolMessage(ProtocolMessage Message) {
        this.Type = Message.Type;
        this.ParametersList = Message.ParametersList;
    }

    /**
     * ProtocolMessage Constructor
     * @param Message Message String
     */
    public ProtocolMessage(String Message) {
        ProtocolMessage temp = new ProtocolMessage(parseMessage(Message));
        this.ParametersList = temp.ParametersList;
        this.Type = temp.Type;
    }

    /**
     * Parse a String message to create a ProtocolMessage Object
     * @param Message String message format
     * @return a ProtocolMessage object
     */
    static private ProtocolMessage parseMessage(String Message){
        int indexSeparator = Message.indexOf(CommunicationProtocol.Separator);
        if(indexSeparator > 0) {          //the separatof was found
            String type = Message.substring(0, indexSeparator-1);
            int indexFirstBegin = Message.indexOf(CommunicationProtocol.BeginParameter, indexSeparator);
            String[] list = Message.substring(indexFirstBegin).split(CommunicationProtocol.EndParameter+CommunicationProtocol.BeginParameter);
            list[list.length-1] = list[list.length-1].substring(0, list[list.length-1].length()-1);             //Ouchhh big function to eliminate the lastDelimeter parameter
            return new ProtocolMessage(type, list);
        } else {
            return null;
        }
    }

    /**
     * Create a prefilled CONNECT message
     * @return a prefilled CONNECT message
     */
    static public ProtocolMessage createConnectMessage() {
        return new ProtocolMessage(CommunicationProtocol.Connect, new ArrayList<String>());
    }

    /**
     * Create a prefilled USER message
     * @param user login of user
     * @param password password of user
     * @return a prefilled USER message
     */
    static public ProtocolMessage createUserMessage(String user, String password) {
        String[] list = {user, password };
        return new ProtocolMessage(CommunicationProtocol.User, list);
    }

    /**
     * Create a prefilled LIST message
     * @return a prefilled LIST message
     */
    static public ProtocolMessage createListMessage() {
        return new ProtocolMessage(CommunicationProtocol.List, new ArrayList<String>());
    }

    /**
     * Create a prefilled DIR message
     * @return a prefilled DIR message
     */
    static public ProtocolMessage createDirMessage() {
        return new ProtocolMessage(CommunicationProtocol.Dir, new ArrayList<String>());
    }

    /**
     * Create a prefilled CHGDIR message
     * @param path path of the dir
     * @return a prefilled CHGDIR message
     */
    static public ProtocolMessage createChgdirMessage(String path) {
        return new ProtocolMessage(CommunicationProtocol.Chgdir, path);
    }

    /**
     * Create a prefilled GET message
     *
     * <b>WARNING:AFTER THE SENT OF THIS MESSAGE, THE SERVER WILL BE IN ATTEMPT WHILE A ENDGET MESSAGE WAS RECEIVED</b>
     * @param filename filename of getted file
     * @param password password to decrypt the file
     * @return a prefilled GET message
     */
    static public ProtocolMessage createGetMessage(String filename, String password) {
        String[] list = {filename, password };
        return new ProtocolMessage(CommunicationProtocol.Get, list);
    }

    /**
     * Create a prefilled POST message
     *
     * <b>WARNING:AFTER THE SENT OF THIS MESSAGE, THE SERVER WILL BE IN ATTEMPT WHILE A ENDPOST MESSAGE WAS RECEIVED</b>
     * @param filename filename of posted file
     * @param password password to encrypt the file
     * @return a prefilled POST message
     */
    static public ProtocolMessage createPostMessage(String filename, String password) {
        String[] list = {filename, password};
        return new ProtocolMessage(CommunicationProtocol.Post, list);
    }

    /**
     * Create a prefilled ENDGET message
     * @return a prefilled ENDGET message
     */
    static public ProtocolMessage createEndgetMessage() {
        return new ProtocolMessage(CommunicationProtocol.Endget, new ArrayList<String>());
    }

    /**
     * Create a prefilled ENDPOST message
     * @return a prefilled ENDPOST message
     */
    static public ProtocolMessage createEndpostMessage() {
        return new ProtocolMessage(CommunicationProtocol.Endpost, new ArrayList<String>());
    }

    /**
     * Create a prefilled QUIT message
     * @return a prefilled QUIT message
     */
    static public ProtocolMessage createQuitMessage() {
        return new ProtocolMessage(CommunicationProtocol.Quit, new ArrayList<String>());
    }

    /**
     * Create a prefilled CREATEDIR message
     * @param foldername folder to create
     * @param description description of this folder
     * @param hidden hidden or not (true/false)
     * @return a prefilled CREATEDIR message
     */
    static public ProtocolMessage createCreatedirMessage(String foldername, String description, String hidden) {
        String[] list = {foldername, description, hidden};
        return new ProtocolMessage(CommunicationProtocol.Createdir, list);
    }

    /**
     * Create a prefilled NEWDIR message
     * @param foldername folder to create
     * @param description description of this folder
     * @param hidden hidden or not (true/false)
     * @return a prefilled NEWDIR message
     */
    static public ProtocolMessage createNewdirMessage(String foldername, String description, String hidden) {
        String[] list = {foldername, description, hidden};
        return new ProtocolMessage(CommunicationProtocol.Newdir, list);
    }
}
